"""
场景创建和管理模块
"""
import uuid
import json
import os
from datetime import datetime
from typing import Dict, List, Optional, Any

from models.scene import Scene


class SceneManager:
    """
    场景管理器，负责场景的创建、编辑、复制、删除等操作
    """
    
    def __init__(self, storage_path: str = "data/scenes"):
        """
        初始化场景管理器
        
        Args:
            storage_path: 场景存储路径
        """
        self.storage_path = storage_path
        os.makedirs(storage_path, exist_ok=True)
    
    def create_scene(self, name: str, description: str, scene_type: str, 
                     related_db: Optional[str] = None) -> Scene:
        """
        创建新场景
        
        Args:
            name: 场景名称
            description: 场景描述
            scene_type: 场景类型
            related_db: 关联的数据库ID
            
        Returns:
            创建的场景对象
        """
        scene_id = str(uuid.uuid4())
        created_at = datetime.now().isoformat()
        
        scene = Scene(
            id=scene_id,
            name=name,
            description=description,
            scene_type=scene_type,
            related_db=related_db,
            created_at=created_at,
            updated_at=created_at,
            status="created",
            current_step=0,
            parameters={},
            data_sources=[],
            calculation_results={}
        )
        
        # 保存场景
        self._save_scene(scene)
        
        return scene
    
    def get_scene(self, scene_id: str) -> Optional[Scene]:
        """
        获取指定ID的场景
        
        Args:
            scene_id: 场景ID
            
        Returns:
            场景对象，如果不存在则返回None
        """
        scene_path = os.path.join(self.storage_path, f"{scene_id}.json")
        if not os.path.exists(scene_path):
            return None
        
        with open(scene_path, 'r', encoding='utf-8') as f:
            scene_data = json.load(f)
            
        return Scene(**scene_data)
    
    def list_scenes(self, filters: Optional[Dict[str, Any]] = None) -> List[Scene]:
        """
        列出所有场景，可根据过滤条件筛选
        
        Args:
            filters: 过滤条件，如 {"scene_type": "sales_forecast"}
            
        Returns:
            符合条件的场景列表
        """
        scenes = []
        
        for filename in os.listdir(self.storage_path):
            if filename.endswith('.json'):
                scene_path = os.path.join(self.storage_path, filename)
                with open(scene_path, 'r', encoding='utf-8') as f:
                    scene_data = json.load(f)
                    
                # 应用过滤条件
                if filters:
                    match = True
                    for key, value in filters.items():
                        if key in scene_data and scene_data[key] != value:
                            match = False
                            break
                    
                    if not match:
                        continue
                
                scenes.append(Scene(**scene_data))
        
        # 按更新时间排序，最新的在前
        scenes.sort(key=lambda x: x.updated_at, reverse=True)
        return scenes
    
    def update_scene(self, scene: Scene) -> Scene:
        """
        更新场景信息
        
        Args:
            scene: 更新后的场景对象
            
        Returns:
            更新后的场景对象
        """
        scene.updated_at = datetime.now().isoformat()
        self._save_scene(scene)
        return scene
    
    def delete_scene(self, scene_id: str) -> bool:
        """
        删除场景
        
        Args:
            scene_id: 场景ID
            
        Returns:
            删除是否成功
        """
        scene_path = os.path.join(self.storage_path, f"{scene_id}.json")
        if not os.path.exists(scene_path):
            return False
        
        os.remove(scene_path)
        return True
    
    def copy_scene(self, scene_id: str, new_name: Optional[str] = None) -> Optional[Scene]:
        """
        复制场景
        
        Args:
            scene_id: 要复制的场景ID
            new_name: 新场景名称，默认为"Copy of {原场景名称}"
            
        Returns:
            复制后的新场景对象，如果原场景不存在则返回None
        """
        original_scene = self.get_scene(scene_id)
        if not original_scene:
            return None
        
        # 创建新场景
        new_scene_id = str(uuid.uuid4())
        created_at = datetime.now().isoformat()
        
        # 设置新名称
        if not new_name:
            new_name = f"Copy of {original_scene.name}"
        
        # 复制场景数据，但重置ID和时间戳
        new_scene = Scene(
            id=new_scene_id,
            name=new_name,
            description=original_scene.description,
            scene_type=original_scene.scene_type,
            related_db=original_scene.related_db,
            created_at=created_at,
            updated_at=created_at,
            status="created",
            current_step=0,
            parameters=original_scene.parameters.copy(),
            data_sources=original_scene.data_sources.copy(),
            calculation_results={}  # 不复制计算结果
        )
        
        # 保存新场景
        self._save_scene(new_scene)
        
        return new_scene
    
    def update_scene_status(self, scene_id: str, status: str, current_step: int) -> Optional[Scene]:
        """
        更新场景状态和当前步骤
        
        Args:
            scene_id: 场景ID
            status: 新状态
            current_step: 当前步骤索引
            
        Returns:
            更新后的场景对象，如果场景不存在则返回None
        """
        scene = self.get_scene(scene_id)
        if not scene:
            return None
        
        scene.status = status
        scene.current_step = current_step
        scene.updated_at = datetime.now().isoformat()
        
        self._save_scene(scene)
        return scene
    
    def search_scenes(self, query: str) -> List[Scene]:
        """
        搜索场景
        
        Args:
            query: 搜索关键词
            
        Returns:
            匹配的场景列表
        """
        query = query.lower()
        results = []
        
        for scene in self.list_scenes():
            # 在名称和描述中搜索关键词
            if (query in scene.name.lower() or 
                query in scene.description.lower()):
                results.append(scene)
        
        return results
    
    def _save_scene(self, scene: Scene) -> None:
        """
        保存场景到文件
        
        Args:
            scene: 场景对象
        """
        scene_path = os.path.join(self.storage_path, f"{scene.id}.json")
        
        with open(scene_path, 'w', encoding='utf-8') as f:
            # 将Scene对象转换为字典并保存为JSON
            json.dump(scene.dict(), f, ensure_ascii=False, indent=2)